package com.axon.mvc.helpers
{
	import com.axon.base.helpers.AxReflectionUtils;
	import com.axon.mvc.patterns.command.AxSimpleCommand;
	import com.axon.mvc.patterns.mediator.AxMediator;
	
	import org.puremvc.as3.interfaces.INotification;
	
	public class AxMvcUtils
	{
		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static const PREFIX_EVENT				: String = "event"
		public static const PREFIX_EXEC					: String = "exec"
		public static const PREFIX_RESP					: String = "resp"
		public static const PREFIX_BRCAST				: String = "brcast"
		
		public static const PREFIX_AX_VERB				: String = "AxVerb"

		public static const SUFIX_COMMAND 				: String = "Command";
		public static const SUFIX_VIEW	 				: String = "View";
		public static const SUFIX_MEDIATOR				: String = "Mediator";
		public static const SUFIX_PROXY 				: String = "Proxy";
		
		public static const SUFIX_SUCCESS				: String = "Success";
		public static const SUFIX_FAILURE				: String = "Failure";
		
		public static const TERM_MODEL					: String = "model";
		public static const TERM_REQUEST_NAME			: String = "requestName";
		public static const TERM_TEXT					: String = "text";
		public static const TERM_TITLE					: String = "title";
		public static const TERM_SENDER					: String = "sender";
		public static const TERM_BODY					: String = "body";
		public static const TERM_EXTRA_INFO				: String = "extraInfo";
		public static const TERM_APP_COMMAND			: String = "AppCommand";
		public static const TERM_SESSION_PROXY			: String = "SessionProxy";
		
		public static const SUBPATH_CONTROLLERS			: String = "controllers";

		public static const SUBPATH_VIEWS				: String = "views";
		public static const SUBPATH_COMPONENTS			: String = "components";
		public static const SUBPATH_MEDIATORS			: String = "mediators";
		public static const SUBPATH_VIEWS_COMPONENTS	: String = SUBPATH_VIEWS + "." + SUBPATH_COMPONENTS;
		public static const SUBPATH_VIEWS_MEDIATORS		: String = SUBPATH_VIEWS + "." + SUBPATH_MEDIATORS;

		public static const SUBPATH_MODELS				: String = "models";
		public static const SUBPATH_PROXIES				: String = "proxies";
		public static const SUBPATH_VO					: String = "vo";
		public static const SUBPATH_MODELS_VO			: String = SUBPATH_MODELS + '.' + SUBPATH_VO;
		public static const SUBPATH_MODELS_PROXIES		: String = SUBPATH_MODELS + '.' + SUBPATH_PROXIES;

		public static const FULL_PATH_APP_COMMAND		: String = SUBPATH_CONTROLLERS + "." + TERM_APP_COMMAND;
		
		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function getMediatorClassNameByViewInstance(viewComponent: Object): String
		{
			return AxReflectionUtils.getClassFullPathByInstance(viewComponent).
						replace(new RegExp("\\d*" + SUFIX_VIEW + "$", ""), SUFIX_MEDIATOR).
						replace(new RegExp("\\d*" + SUBPATH_VIEWS_COMPONENTS + "\\d*", ""), SUBPATH_VIEWS_MEDIATORS);
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function getMediatorClassReferenceByViewInstance(view: Object): Class
		{
			return AxReflectionUtils.getClassRefByFullPath(
						AxReflectionUtils.getClassFullPathByInstance(view).
						replace(new RegExp("\\d*" + SUBPATH_VIEWS_COMPONENTS + "\\d*", ""), SUBPATH_VIEWS_MEDIATORS).
						replace(new RegExp("\\d*" + SUFIX_VIEW + "$", ""), SUFIX_MEDIATOR) );
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function getViewClassNameByMediatorInstance(mediator: Object): String
		{
			return getViewClassNameByMediatorName(AxReflectionUtils.getClassNameByInstance(mediator));
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function getViewClassNameByMediatorName(name: String): String
		{
			return name.replace(new RegExp("\\d*" + SUFIX_MEDIATOR + "$", ""), SUFIX_VIEW); 
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function getViewClassRefByMediatorInstance(mediator: AxMediator): Class
		{
			return AxReflectionUtils.getClassRefByFullPath(
						AxReflectionUtils.getClassFullPathByInstance(mediator).
						replace(new RegExp("\\d*" + SUBPATH_VIEWS_MEDIATORS + "\\d*", ""), SUBPATH_VIEWS_COMPONENTS).
						replace(new RegExp("\\d*" + SUFIX_MEDIATOR + "\\d*", ""), SUFIX_VIEW) );
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function getCommandClassRefByModelClassRef(modelClass: Class): Class
		{
			return AxReflectionUtils.getClassRefByFullPath( 
						AxReflectionUtils.getClassFullPathByInstance(modelClass).
						replace(new RegExp("\\d*" + SUBPATH_MODELS_VO + "\\d*", ""), SUBPATH_CONTROLLERS) + SUFIX_COMMAND );
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function isNotificationResponse(notificationName: String): Boolean
		{
			return (isNotificationResponseSuccess(notificationName) || 
				isNotificationResponseFailure(notificationName));
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function isNotificationResponseSuccess(notificationName: String): Boolean
		{
			return (notificationName.search(new RegExp("\\d*" + SUFIX_SUCCESS + "$", "")) != -1);
		}
		
		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function isNotificationResponseFailure(notificationName: String): Boolean
		{
			return (notificationName.search(new RegExp("\\d*" + SUFIX_FAILURE + "$", "")) != -1);
		}
		
		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function getResponsePrefixName(notificationName: String): String
		{
			var pos: int = (isNotificationResponseSuccess(notificationName)) ?
							notificationName.search(new RegExp("\\d*" + SUFIX_SUCCESS + "$", "")) :
							notificationName.search(new RegExp("\\d*" + SUFIX_FAILURE + "$", ""));
			
			return (pos == -1) ? notificationName : notificationName.substr(0, pos);
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function getCommandPrefixName(command: Object): String
		{
			return AxReflectionUtils.getClassNameByInstance(command).replace(new RegExp("\\d*" + SUFIX_COMMAND + "$", ""), "");
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function getProxyPrefixName(proxy: Object): String
		{
			return AxReflectionUtils.getClassNameByInstance(proxy).replace(new RegExp("\\d*" + SUFIX_PROXY + "$", ""), "");
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function extractActionNameFromNotificationName(command: AxSimpleCommand, note: INotification): String
		{
			return (AxReflectionUtils.getClassFullPathByInstance(command) == AxMvcUtils.FULL_PATH_APP_COMMAND) ?
						note.getName().replace(new RegExp("^" + PREFIX_AX_VERB + "\\d*", ""), "") :
						note.getName().replace(new RegExp("^" + getCommandPrefixName(command) + "\\d*", ""), "");
		}				
						
		//////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function removeAxVerbPrefix(name: String): String
		{
			return name.replace(new RegExp("^" + PREFIX_AX_VERB + "\\d*", ""), "");
						
		}

	}		
}